package sample;

import CmdHandle.HandleCommand;
import CmdHandle.MakeLogPackage;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import utils.CommandDefault;
import utils.CommonComponent;
import xmlParse.XmlParser;

import java.io.*;
import java.util.Objects;
import java.util.concurrent.*;

public class UIHandle {
    TextField source;
    TextField target;
    //界面日志输出
    Text textLog;
    //通过线程池来执行
    ExecutorService serviceThread;
    HandleCommand handleCommand;
    Stage mStage;
    //创建一个栅格形态的布局，以label：TextField形式显示
    public GridPane createGrid(Stage stage, String[] stringBuilder) {
        GridPane grid = initGrid();
        mStage=stage;
        initHandle();
        //原始路径
        Text sourceApk = new Text(stringBuilder[0]);
        sourceApk.setFont(Font.font("Tahoma", FontWeight.LIGHT, 15));
        grid.add(sourceApk, 0, 0);
        source = new TextField();
        grid.add(source, 1, 0);
        getPath(stage, grid, 0);
        //apk解包
        createDecodeApk(grid, stringBuilder.length);
        //apk反编译
        createCompileApk(grid, stringBuilder.length);
        //apk签名
        apkSigned(grid, stringBuilder.length);
        //一键打包
        makeLogApk(grid);
        //dex2Jar
        //
        //显示日志
        logShow(grid);
        return grid;
    }

    private void initHandle() {
        serviceThread=Executors.newFixedThreadPool(2);
    }
    //一键打包,采取默认的形式，通过要打包的apk
    //未完待续。。。
    private void makeLogApk(GridPane grid) {
        Button button = new Button();
        button.setText("一键打包");
        button.setOnAction((ActionEvent e) -> {
            if (source.getText().isEmpty()) {
                handleTextFieldIsEmpty();
            }

            //.apk
            String sourcePath = source.getText();
            File filename = new File(sourcePath);
            //目录
            String targetPath = target.getText().substring(0, target.getText().lastIndexOf(getPlatformSeparator()));
            //反编译apk文件夹
            String decodeTargetPath = target.getText().substring(0, target.getText().lastIndexOf("."));
            String cmdDecode = "java -jar apktool.jar d " + sourcePath + " -o " + decodeTargetPath;
            //需要处理
            String cmdCompile = "java -jar apktool.jar b " + decodeTargetPath;
            //需要处理
            String cmdSigned = "jarsigner -verbose -keystore feihu1.jks " +
                    "-signedjar " + decodeTargetPath + getPlatformSeparator() + "dist" + getPlatformSeparator() + "game_signed.apk -storepass 123qwe " + decodeTargetPath + getPlatformSeparator() + "dist" + getPlatformSeparator() + filename.getName() + " key0";

            final String[] cmd={cmdDecode,cmdCompile,cmdSigned};
            MakeLogPackage makeLogPackage=new MakeLogPackage(source,target,cmd,textLog);
            ProgressBar bar=CommonComponent.createProgressBar(new Stage());
            bar.progressProperty().bind( makeLogPackage.progressProperty());
            serviceThread.submit(makeLogPackage);
        });
        grid.add(button, 0, 3);
    }

    //签名操作
    private void apkSigned(GridPane grid, int row) {
        Button button = new Button();
        button.setText("签名");
        //进行签名
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                if (source.getText().isEmpty()) {
                    handleTextFieldIsEmpty();
                    return;
                }
                String sourcePath = source.getText();
                String targetPath = target.getText().substring(0, target.getText().lastIndexOf("/"));
                //目标文件
                File file = new File(targetPath + getPlatformSeparator() + "game_signed.apk");
                if (file.exists()) {
                    file.delete();
                }
                Runtime run = Runtime.getRuntime();
                String cmd = "jarsigner -verbose -keystore feihu1.jks " +
                        "-signedjar " + targetPath + getPlatformSeparator() + "game_signed.apk -storepass 123qwe " + sourcePath + " key0";
                serviceThread.submit(createTask(cmd));

            }
        });
        grid.add(button, 2, row);
    }

    private void logShow(GridPane grid) {
        //日志信息查看
        textLog = new Text();
        textLog.setText("");
        //超出部分滚动显示
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(textLog);
        scrollPane.setFitToHeight(true);
        scrollPane.setFitToWidth(true);
        grid.add(scrollPane, 0, 5, 3, 5);
    }


    private void createCompileApk(GridPane grid, int row) {
        Button button = new Button();
        button.setText("反打包APK");
        button.setOnAction((ActionEvent e) -> {
            if (source.getText().isEmpty()) {
                handleTextFieldIsEmpty();
                return;
            }
            String sourcePath = source.getText().substring(0, target.getText().lastIndexOf("."));
            //打包生成路径
            File file = new File(sourcePath + getPlatformSeparator() + "dist");
            //获取AndroidManifest.xml文件
            File manifest=new File(sourcePath+getPlatformSeparator(),"AndroidManifest.xml");
            XmlParser xmlParser=new XmlParser(manifest);
            xmlParser.injectDebuggable();
            //如果有文件就全部删除
            if (file.list() != null) {
                for (File f : Objects.requireNonNull(file.listFiles())) {
                    f.delete();
                }
            }
            Runtime run = Runtime.getRuntime();
            String cmd = "java -jar apktool.jar b " + sourcePath;
            System.out.println("反打包：" + cmd);
            serviceThread.submit(createTask(cmd));
        });
        grid.add(button, 1, row);
    }

    private void createDecodeApk(GridPane grid, int row) {
        Button button = new Button();
        button.setText("反编译APK");
        button.setOnAction((ActionEvent e) -> {
            if (source.getText().isEmpty()) {
                handleTextFieldIsEmpty();
                return;
            }
            String sourcePath = source.getText();
            String targetPath = target.getText().substring(0, target.getText().lastIndexOf("."));
            Runtime run = Runtime.getRuntime();
            String cmd = "java -jar apktool.jar d " + sourcePath + " -o " + targetPath;
            serviceThread.submit(createTask(cmd));
        });
        grid.add(button, 0, row);
    }



    //判断原路径和目标路径是否为空
    private void handleTextFieldIsEmpty() {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setContentText("请选择目标和原路径");
        alert.setTitle("警告");
        alert.setHeaderText("注意");
        alert.showAndWait();
    }

    //建立一个按钮打开文件浏览
    private void getPath(Stage stage, GridPane grid, int row) {
        Button button = new Button();
        button.setText("...");
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("open file");
        button.setOnAction((ActionEvent e) -> {
            File file = fileChooser.showOpenDialog(stage);
            if (row == 0) {
                source.setText(file.getAbsolutePath());
                target=source;
            }
            //不会执行到
            else if (row == 1) {
                target.setText(file.getAbsolutePath());
            }
        });
        grid.add(button, 2, row);
    }


    //初始化布局
    private GridPane initGrid() {
        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25, 25, 25, 25));
        return grid;
    }

    private String getPlatformSeparator() {
        return CommandDefault.getPlatformSeparator();
    }

    //建立一个后台任务
    private Runnable createTask(String mCmd) {
        handleCommand=new HandleCommand(mCmd,textLog);
        ProgressBar bar=CommonComponent.createProgressBar(new Stage());
        bar.progressProperty().bind(handleCommand.progressProperty());
        return handleCommand;
    }
}
